class FirewallRule(object):
    def __init__(self):
        self.directions = set()  # 方向
        self.protocols = set()  # 协议
        self.ips_discrete = set()  # 单个地址
        self.ips_range = set()  # 地址范围

    def add_direction(self, direction: str):
        self.directions.add(direction)

    def add_protocol(self, protocol: str):
        self.protocols.add(protocol)

    def add_ips_discrete(self, ip: str):
        self.ips_discrete.add(ip)

    def add_ips_range(self, ip_range: str):
        # 转化为字节校验
        low_ip, high_ip = ip_range.split("-")
        low_ip_byte = self.ip_to_byte_array(low_ip)
        high_ip_byte = self.ip_to_byte_array(high_ip)
        self.ips_range.add((low_ip_byte, high_ip_byte))

    def contains_protocol(self, protocol: str):
        return protocol in self.protocols

    def contains_direction(self, direction: str):
        return direction in self.directions

    @staticmethod
    def ip_to_byte_array(ip: str) -> bytes:
        ip_split = ip.split(".")
        ip_split = [int(byte) for byte in ip_split]
        return bytes(ip_split)

    def is_within_ip_range(self, ip_address):
        if ip_address in self.ips_discrete:
            return True

        ip_address_byte = self.ip_to_byte_array(ip_address)
        for ip_range in self.ips_range:
            low_ip_byte, high_ip_byte = ip_range
            if low_ip_byte <= ip_address_byte <= high_ip_byte:
                return True
        return False
